<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>svg打钩动画</title>
  <style>
    body {
      display: flex;
      justify-content: center;
      align-items: center;
      min-height: 100vh;
      flex-direction: column;
      background: #000;
      color: white;
    }

    h2 {
      font-family: Helvetica;
      font-size: 36px;
      margin-top: 40px;
      color: #333;
      opacity: 0;
    }

    .circle-wrapper {
      position: relative;
    }

    .timer-wrapper {
      margin-bottom: 20px;
    }

    .targetTime {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      font-size: 70px;
    }
    .circle {
      stroke-dasharray: 1194;
      stroke-dashoffset: 2388;
      animation-fill-mode: forwards;
    }

    #canvas{
      display: none;
    }
    @keyframes circle {
      from {
        stroke-dashoffset: 2388;

      }

      to {
        stroke-dashoffset: 3582;

      }
    }

  </style>
</head>

<body>
  <div class="timer-wrapper">
    提醒时间：<input type="time" value="00:00:00" id="selectTimer">
    <button id="start">开始</button>
  </div>
  <select id="animateSelect">
    <option value ="svg">svg</option>
    <option value ="canvas">canvas</option>

    
  </select>
  <div class="circle-wrapper"  id="svg">
    <svg width="400" height="400">
      <circle fill="none" stroke="#e67e22" stroke-width="20" cx="200" cy="200" r="190" class="circle"
        stroke-linecap="round" transform="rotate(-90 200 200) " />
    </svg>
    <span class="targetTime"></span>
  </div>

  <canvas id="canvas"></canvas>

 
<script>
  //  时间计算
    function getResidueDate(start_date, end_date) {
      let residue = end_date - start_date;
      let days = Math.floor(residue / 1000 / 60 / 60 / 24);
      let hours = Math.floor((residue / 1000 / 60 / 60) % 24);
      let minutes = Math.floor((residue / 1000 / 60) % 60);
      let seconds = Math.floor((residue / 1000) % 60);

      days = days < 10 ? "0" + days : days;
      hours = hours < 10 ? "0" + hours : hours;
      minutes = minutes < 10 ? "0" + minutes : minutes;
      seconds = seconds < 10 ? "0" + seconds : seconds;
      return `${hours}:${minutes}:${seconds}`
    }

    // svg 动画
    let animateType = 'svg'
    let startTime = ''
    let during = ''
    let timer = null
    let targetTimeText = ''

    function svgAnimate(){
      timer = setInterval(() => {
        let targetTimeText = getResidueDate(+new Date(), startTime + during)
        console.log(targetTimeText)
        targetTime = document.querySelector('.targetTime')
        targetTime.innerHTML = targetTimeText
        document.querySelector('.circle').setAttribute('style', `animation: circle ${during / 1000}s ease-in-out;`)
        if (+new Date() > startTime + during) {
          clearInterval(timer)
          targetTime.innerHTML = ''
        }
      }, 1000)
    }


    // canvas 动画
    let  ctx = canvas.getContext('2d');
    let  mW = canvas.width = 500;
    let  mH = canvas.height = 500;
    let  lineWidth = 10;
    let  r = mW / 2; //中间位置
    let  cR = r - 4 * lineWidth; //圆半径
    // let  startAngle = -(1 / 2 * Math.PI); //开始角度
    // let  endAngle = startAngle + 2 * Math.PI; //结束角度
    let  startAngle = (Math.PI / 180) *-90; //开始角度
    let  endAngle = (Math.PI / 180) * 270; //结束角度
    // let  step = 1 * (Math.PI / 180); //偏移角度量 , 时间 / 360
    let  fontSize = 70; //字号大小
    let  tmpAngle = startAngle; //临时角度变量
  
    //渲染函数
    let  canvasAnimate = function(){
      // let  step = 360 /  (during / 1000 ) * (Math.PI / 180)//偏移角度量 , 时间 / 360
      let step = 0.06

      // 基线条件
      if(tmpAngle >= endAngle){
        return;
      }else if(tmpAngle + step > endAngle){
        tmpAngle = endAngle;
      }else{
        tmpAngle += step;
      }


      ctx.clearRect(0, 0, mW, mH);
      //画圈
      ctx.beginPath();
      ctx.lineWidth = lineWidth;
      ctx.strokeStyle = '#e67e22';
      ctx.arc(r, r, cR,  tmpAngle,startAngle );
      ctx.stroke();
      ctx.closePath();
      //写字
      ctx.fillStyle = 'white';
      ctx.font= fontSize + 'px Microsoft Yahei';
      ctx.textAlign='center';
      let targetTimeText = getResidueDate(+new Date(), startTime + during)
      // console.log(targetTimeText)
      ctx.fillText(targetTimeText, r, r + fontSize / 2);
      requestAnimationFrame(canvasAnimate);
      // deltaTime = 13.33ms about
      // setTimeout(()=>{
      //   canvasAnimate()
      // },1000)
  
    };


    function animateStart() {
      if(animateType==='svg'){
        svgAnimate()
      }else {
        canvasAnimate();

      }
      
    }
    selectTimer.addEventListener('change', (event) => {
      during = event.target.valueAsNumber
    })

    start.addEventListener('click', () => {
      startTime = +new Date()
      animateStart()
    })


    animateSelect.addEventListener('click', (event) => {
       animateType =  event.target.value
       if(animateType==='canvas'){
        document.getElementById('canvas').style.display="block";
        document.getElementById('svg').style.display="none";
       }else{
        document.getElementById('svg').style.display="block";
        document.getElementById('canvas').style.display="none";
       }
    })

    
  </script>



</body>

</html>